package com.syezon.wifikey.speed;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

public class DUProgressView extends View {

    private Paint mPaint;
    private ValueAnimator mAnim;

    private float mIndicatorWidth;
    private float mIndicatorHeight;

    private float mStartOffset;
    private boolean mReverse;
    private RectF mIndicatorRectF;
    private int mWidth;

    public DUProgressView(Context context) {
        super(context);
        init();
    }

    public DUProgressView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public DUProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mIndicatorHeight = dp2px(5);
        mIndicatorWidth = dp2px(70);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.parseColor("#8FFFFFFF"));
        mIndicatorRectF = new RectF(0, 0, mIndicatorWidth, mIndicatorHeight);
        invalidate();
    }

    public void reset() {
        if (mAnim != null && mAnim.isRunning()) {
            mAnim.cancel();
        }
        mReverse = false;
        mStartOffset = -mIndicatorWidth;
        mIndicatorRectF.set(0, 0, 0, 0);
        invalidate();
    }

    public boolean isAnim() {
        return mAnim != null && mAnim.isRunning();
    }

    public boolean isReverseAnim() {
        return mReverse && mAnim != null && mAnim.isRunning();
    }

    public void setReverse(final boolean reverse) {
        this.mReverse = reverse;
        mPaint.setShader(null);
        if (mAnim != null && mAnim.isRunning()) {
            mAnim.cancel();
        }
        if (reverse) {
            mStartOffset = mWidth;
            mAnim = ValueAnimator.ofFloat(mWidth, 0);
        } else {
            mStartOffset = 0;
            mAnim = ValueAnimator.ofFloat(0, mWidth - mIndicatorWidth);
        }
        mAnim.setDuration(1500);
        mAnim.setRepeatCount(ValueAnimator.INFINITE);
        mAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float animatedFraction = animation.getAnimatedFraction();
                double sin = Math.sin(Math.PI * animatedFraction);
                mPaint.setAlpha((int) (255 * sin));
//                mPaint.setAlpha((int) (255 - 255 * animatedFraction));
                mStartOffset = (float) animation.getAnimatedValue();
                float width = mIndicatorWidth * animatedFraction;
                mIndicatorRectF.set(mStartOffset, 0, mStartOffset + width, mIndicatorHeight);
                int[] colors = new int[2];
                if (reverse) {
                    colors[0] = Color.parseColor("#FFFFFF");
                    colors[1] = Color.parseColor("#19FFFFFF");
                } else {
                    colors[0] = Color.parseColor("#19FFFFFF");
                    colors[1] = Color.parseColor("#FFFFFF");
                }
                mPaint.setShader(new LinearGradient(mStartOffset, mIndicatorHeight / 2, mStartOffset + width, mIndicatorHeight / 2, colors, null, Shader.TileMode.REPEAT));
                invalidate();
            }
        });
        mAnim.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {

            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                if (reverse) {
                    mStartOffset = mWidth;
                } else {
                    mStartOffset = -mIndicatorWidth;
                }
            }
        });
        mAnim.start();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int size = MeasureSpec.getSize(widthMeasureSpec);
        mWidth = size;
        setMeasuredDimension(size, (int) mIndicatorHeight);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = getWidth();
        if (mReverse) {
            mStartOffset = mWidth;
        } else {
            mStartOffset = -mIndicatorWidth;
        }
        mIndicatorRectF.set(mStartOffset, 0, mStartOffset + mIndicatorWidth, mIndicatorHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRoundRect(mIndicatorRectF, dp2px(5), dp2px(5), mPaint);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mAnim != null && mAnim.isRunning()) {
            mAnim.cancel();
        }
    }

    private float dp2px(float dp) {
        return getContext().getResources().getDisplayMetrics().density * dp + 0.5f;
    }
}
